###############################################################################
#
# Copyright (c) 2011 Rainmaker Entertainment
# All Rights Reserved.
#
# This file contains unpublished confidential and proprietary
# information of Rainmaker Entertainment.  The contents of this file
# may not be copied or duplicated, in whole or in part, by any
# means, electronic or hardcopy, without the express prior
# written permission of Rainmaker Entertainment.
#
#    $HeadURL: http://pt/src/trunk/maya/outsource/rnkOutsourceChecker/operations/ofRig.py $
#    $Revision: 67856 $
#    $Author: wmakari $
#    $Date: 2013-09-17 18:23:18 -0700 (Tue, 17 Sep 2013) $
#
###############################################################################

import traceback
import re

try :
    import maya.cmds as cmds
    import maya.mel as mel
    import maya.OpenMaya as OpenMaya
except :
    traceback.print_exc()
    print "Can't load Maya modules."
    

import core
reload(core)


def doesHookNodeExist(assetRoot, *args, **kw):
    """ 
    @brief look for the hook node named 
    @return : Bool
    
    ARGS :
        @param assetRoot - String - Asset root node.
    """
    issues = []
    hook = 'global_ctrl_zero'

    if len(cmds.ls(hook)) > 1:
        allowPublish = False
        msg="We found more than one global_ctrl_zero nodes."

    elif len(cmds.ls(hook)) < 1:
        allowPublish = False
        msg="We could not find global_ctrl_zero."

    else:
        allowPublish = True
        msg="Good! We found it."

    return core.checkResult(allowPublish=allowPublish, msg=msg)

doesHookNodeExist.modifiedScene = False
doesHookNodeExist.uiName = 'Check if global_ctrl_zero exists'
doesHookNodeExist.revision = "$Revision: 67856 $".split()[1]



def doesItHaveParents(assetRoot, assetClass='creatures', *args, **kw):
    """
    """
    print assetClass, assetClass.__class__, assetClass == 'vehicle'
    if assetClass == 'vehicle':
        return core.checkResult(allowPublish=True, msg="We won't check for this asset %s:%s." % (assetRoot, assetClass))

    controllers = core.getCtrlList(assetRoot)
    if not controllers:
        return core.checkResult(allowPublish=False, msg="could not find any controllers")

    issues = set()
    for controller in controllers:
        if controller.lower() in ['visibility', 'visibility_ctrl', 'globaltrans', 'globaltransa', 'globaltransb', 'localtrans']:
            continue

        if cmds.nodeType(controller) == 'transform':
            for suffix in ['_PH', '_SN']:
                if controller.endswith(suffix):
                    break
            else:
                for suffix in ['_PH', '_SN']:
                    if not cmds.objExists('%s%s' % (controller, suffix)):
                        issues.add(controller)

    if issues:
        return core.checkResult(allowPublish=False, msg="Please make sure that those nodes have _PH and _SN for constraint tool.", nodes=list(issues))
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

doesItHaveParents.modifiedScene = False
doesItHaveParents.uiName = 'Check if every control has _SN and _PH groups'
doesItHaveParents.revision = "$Revision: 67856 $".split()[1]



def __isItLocked(nodeName):
    for attr in ["sx", "sy", "sz"]:
        if not cmds.getAttr("%s.%s" % (nodeName, attr), l=True) or cmds.getAttr("%s.%s" % (nodeName, attr), k=True):
            return False
    else:
        return True

    # in case that the scale parent attribute is locked.
    if not cmds.getAttr("%s.s" % nodeName, l=True) or cmds.getAttr("%s.s" % nodeName, k=True) or cmds.getAttr("%s.s" % nodeName, cb=True):
        return False
    else:
        return True


def __isKeyable(nodeName):
    if cmds.getAttr("%s.v" % nodeName, k=True):
        return True
    else:
        return False


def areParentsMasterNodesLocked(assetRoot, *args, **kw):
    """
    scale attributes of _PH and _SN should be locked.
    """
    controllers = core.getCtrlList(assetRoot)
    if not controllers:
        return core.checkResult(allowPublish=False, msg="could not find any controllers")

    issues = set()
    for controller in controllers:
        if controller.lower() in ['visibility', 'visibility_ctrl', 'globaltrans', 'globaltransa', 'globaltransb', 'localtrans']:
            continue

        if cmds.nodeType(controller) == 'transform':
            for suffix in ['_PH', '_SN']:
                if controller.endswith(suffix):
                    if not __isItLocked(controller) or __isKeyable(controller):
                        issues.add(controller)

            else:
                for suffix in ['_PH', '_SN']:
                    nodeName = '%s%s' % (controller, suffix)
                    if cmds.objExists(nodeName):
                        if not __isItLocked(nodeName) or __isKeyable(nodeName):
                            issues.add(nodeName)

    if issues:
        return core.checkResult(allowPublish=False, msg="Please lock and set keyable off for scale attribtues and set keyable off for visibility attribute.", nodes=list(issues))
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

areParentsMasterNodesLocked.modifiedScene = False
areParentsMasterNodesLocked.uiName = 'Check if scale/vis attrs on _SN and _PH groups are locked'
areParentsMasterNodesLocked.revision = "$Revision: 67856 $".split()[1]



def controllerSuffix(assetRoot, *args, **kw):
    """
    nodes outside of set_ctrl should not ends with _ctrl.
    """
    nodes = cmds.listRelatives(assetRoot, c=True, ad=True)
    if not nodes:
        return core.checkResult(allowPublish=False, msg="Is that possible? There are not any nodes under %s." % assetRoot)

    ctrls = set()
    if cmds.objExists('set_ctrl'):
        ctrls = set(cmds.sets('set_ctrl', q=True))

    nodes = set(nodes)
    nodes.difference_update(ctrls)

    issues = list()
    for n in nodes:
        if n == 'info_ctrl':
            continue

        if n.endswith('ctrl'):
            issues.append(n)

    if issues:
        return core.checkResult(allowPublish=False, msg="Are nodes controllers? If yes, please add to set_ctrl. Otherwise please rename them.", nodes=issues)
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")
controllerSuffix.modifiedScene = False
controllerSuffix.uiName = 'Check for nodes using the suffix _ctrl outside the set_ctrl'
controllerSuffix.revision = "$Revision: 67856 $".split()[1]



def doesVisibility_ctrlExist(assetRoot, *args, **kw):
    """
    checks if visibility_ctrl exists.
    """
    nodes = cmds.listRelatives(assetRoot, c=True, ad=True)
    if not nodes:
        return core.checkResult(allowPublish=False, msg="Is that possible? There are not any nodes under %s." % assetRoot)

    if 'visibility_ctrl' in nodes:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")
    else:
        return core.checkResult(allowPublish=False, msg="visibility_ctrl does not exist.")
doesVisibility_ctrlExist.modifiedScene = False
doesVisibility_ctrlExist.uiName = 'Check if visibility_ctrl exists'
doesVisibility_ctrlExist.revision = "$Revision: 67856 $".split()[1]



def doRootControllersExist(assetRoot, *args, **kw):
    """
    checks if global_ctrl, local_ctrl and all_ctrl exist.
    """
    nodes = cmds.listRelatives(assetRoot, c=True, ad=True)
    if not nodes:
        return core.checkResult(allowPublish=False, msg="Is that possible? There are not any nodes under %s." % assetRoot)

    issues = list()
    for name in ['global_ctrl', 'local_ctrl', 'all_ctrl']:
        if name in nodes:
            continue

        issues.append(name)

    if issues:
        return core.checkResult(allowPublish=False, msg="Could not find %s." % ', '.join(issues))
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

doRootControllersExist.modifiedScene = False
doRootControllersExist.uiName = 'Check if global_ctrl, local_ctrl and all_ctrl exist'
doRootControllersExist.revision = "$Revision: 67856 $".split()[1]



def areRootControllersLocked(assetRoot, *args, **kw):
    """
    checks if scale attributes of global_ctrl, local_ctrl and all_ctrl are locked and set keyable off.
    """
    nodes = cmds.listRelatives(assetRoot, c=True, ad=True)
    if not nodes:
        return core.checkResult(allowPublish=False, msg="Is that possible? There are not any nodes under %s." % assetRoot)

    issues = list()
    for name in ['global_ctrl', 'local_ctrl', 'all_ctrl']:
        if name in nodes:
            if not __isItLocked(name) or __isKeyable(name):
                issues.append(name)

    if issues:
        return core.checkResult(allowPublish=False, msg="Please lock scale attribtues and set keyable off %s." % ', '.join(issues))
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

areRootControllersLocked.modifiedScene = False
areRootControllersLocked.uiName = 'Check if scale/vis attrs on character root controls are locked and unkeyable'
areRootControllersLocked.revision = "$Revision: 67856 $".split()[1]



def checkColorIndex(assetRoot, *args, **kw):
    """
    checks if global_ctrl, local_ctrl and all_ctrl have colored properly.
    --global_ctrl: yellow (color index 22)
    --local_ctrl: dark yellow (color index 24)
    --yellow (color index 22)
    """
    nodes = cmds.listRelatives(assetRoot, c=True, ad=True)
    if not nodes:
        return core.checkResult(allowPublish=False, msg="Is that possible? There are not any nodes under %s." % assetRoot)

    issues = list()
    for name in ['global_ctrl', 'all_ctrl']:
        if name in nodes:
            shape = cmds.listRelatives(name, c=True, type='nurbsCurve')
            if not shape:
                continue

            index = cmds.getAttr("%s.overrideColor" % shape[0])
            if index != 22:
                issues.append(name)

    name = 'local_ctrl'
    if name in nodes:
        shape = cmds.listRelatives(name, c=True, type='nurbsCurve')
        if shape:
            index = cmds.getAttr("%s.overrideColor" % shape[0])
            if index not in [24, 10]:
                issues.append(name)

    if issues:
        return core.checkResult(allowPublish=False, msg="Please check color index of %s." % ', '.join(issues), nodes=issues)
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

checkColorIndex.modifiedScene = False
checkColorIndex.uiName = 'Check color convention for global_ctrl, local_ctrl and all_ctrl'
checkColorIndex.revision = "$Revision: 67856 $".split()[1]



def placeHolderNodesShouldBeIncludedToSet(assetRoot, *args, **kw):
    """
     _PH and _SN nodes need to be in the set_ctrl.
    """
    nodes = cmds.listRelatives(assetRoot, c=True, ad=True)
    if not nodes:
        return core.checkResult(allowPublish=False, msg="Is that possible? There are not any nodes under %s." % assetRoot)

    nodes = [n for n in nodes if n.endswith('_PH') or n.endswith('_SN')]
    nodes = set(nodes)

    ctrls = set()
    if cmds.objExists('set_ctrl'):
        ctrls = set(cmds.sets('set_ctrl', q=True))

    issues = list()
    for n in nodes:
        if n in ctrls:
            continue
        issues.append(n)

    if issues:
        return core.checkResult(allowPublish=False, msg="Those nodes are not in set_ctrl.", nodes=issues)
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

placeHolderNodesShouldBeIncludedToSet.modifiedScene = False
placeHolderNodesShouldBeIncludedToSet.uiName = 'Check if _SN and _PH groups are in set_ctrl'
placeHolderNodesShouldBeIncludedToSet.revision = "$Revision: 67856 $".split()[1]



def doControllersHaveShape(*args, **kw):
    """
    Check if the nodes with the suffix '_ctrl' have at least 1 NURBS curve shape.
    """

    ctrls = set()
    if cmds.objExists('set_ctrl'):
        ctrls = set(cmds.sets('set_ctrl', q=True))

    issues = list()
    for c in ctrls:
        if c.endswith('_PH') or c.endswith('_SN'):
            continue

        if not cmds.listRelatives(c, c=True, type=['nurbsCurve']):
            issues.append(c)

    if issues:
        return core.checkResult(allowPublish=False, msg="Those nodes do not have any shapes as their children.", nodes=issues)
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

doControllersHaveShape.modifiedScene = False
doControllersHaveShape.uiName = 'Check if nodes those which end with _ctrl have at least 1 NURBS curve shape'
doControllersHaveShape.revision = "$Revision: 67856 $".split()[1]



def listDisplayLayers(*args, **kw):
    """
    do not use displayLayer for the purpose to show/hide and reference/normal/template. Only exception is eye_HI_display_layer.
    """
    issues = list()
    for n in cmds.ls(type="displayLayer"):
        if n == "defaultLayer":
            continue

        if not cmds.attributeQuery("__rnkDoNotDelete", n=n, ex=True):
            issues.append(n)

    if issues:
        return core.checkResult(allowPublish=False, msg="Please don't use displayLayers.", nodes=issues)
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")
listDisplayLayers.modifiedScene = False
listDisplayLayers.uiName = 'Check for display layers in the scene, only one allowed is eye_HI_display_layer'
listDisplayLayers.revision = "$Revision: 67856 $".split()[1]



def geoSuffix(*args, **kw):
    """
    """
    root_node = 'of3d_rig'
    if not cmds.objExists(root_node):
        return core.checkResult(allowPublish=False, warning=True, msg="could not found of3d_rig.")

    nodes = cmds.listRelatives(root_node, ad=True, c=True, type='mesh')
    if not nodes:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

    issues = list()
    for node in nodes:
        if cmds.listRelatives(node, p=True):
            parent_node = cmds.listRelatives(node, p=True)[0]
            if parent_node.endswith("_HI"):
                issues.append(parent_node)

    if issues:
        return core.checkResult(allowPublish=False, msg="Please don't use suffix _HI for those nodes.", nodes=issues)
    else:
        return core.checkResult(allowPublish=True, msg="Looks good! Thanks!")

geoSuffix.modifiedScene = False
geoSuffix.uiName = 'Check if displyaLayer exist except for eye_HI_display_layer.'
geoSuffix.revision = "$Revision: 67856 $".split()[1]
